/*
 * fv3tk
 * Copyright (C) 2009  John Pritchard, jdp@syntelos.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package fv3tk.hid;

import fv3tk.Fv3Hid;

import java.nio.ByteBuffer;

/**
 * A device class has static methods for the operation of the class by
 * {@link fv3tk.Fv3Hid}.  See {@link fv3tk.Fv3Hid$Device}.
 * 
 * Instances of the class are events produced by a device, in an
 * iterable list of themselves.
 * 
 * @see fv3tk.Fv3Hid$Device 
 * @see File
 * @see Logitech
 */
public abstract class Device
    extends Object
    implements Fv3Hid.Device,
               InputEvent
{
    /**
     * Read two bytes into an int with Big Endian byte order.
     */
    public final static int ReadShortBen(ByteBuffer buf){
        int value = (((buf.get() & 0xff)<<8)|(buf.get() & 0xff));
        return value;
    }
    public final static void Clear(ByteBuffer buf){

        buf.clear();
    }


    protected volatile int event;

    private volatile boolean alive;

    protected volatile Device list;

    private volatile boolean consumed;


    protected Device(){
        super();
    }


    public int getEventType(){
        return this.event;
    }
    public void consume(){
        this.consumed = true;
    }
    public boolean isConsumed(){
        return this.consumed;
    }
    public boolean alive(){
        return this.alive;
    }
    public Fv3Hid.Device insert(Fv3Hid.Device d){
        if (this.coalesce(d)){
            if (null != this.list)
                ((Device)d).list = this.list;
            return d;
        }
        else {
            ((Device)d).list = this;
            return d;
        }
    }
    public boolean hasNext(){
        return (null != this.list);
    }
    public Fv3Hid.Device next(){
        return this.list;
    }
    /**
     * @see #insert
     */
    public void remove(){
        throw new UnsupportedOperationException();
    }
    public void destroy(){
        if (this.alive){
            this.alive = false;
            Device list = this.list;
            if (null != list){
                this.list = null;
                list.destroy();
            }
        }
    }
    public java.util.Iterator<Fv3Hid.Device> iterator(){
        return this;
    }
    protected boolean coalesce(Fv3Hid.Device d){
        return (((Device)d).event == this.event);
    }

}
